package com.starblink.home.ui

import android.net.Uri
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.apollographql.apollo3.api.Optional
import com.apollographql.apollo3.cache.normalized.FetchPolicy
import com.starblink.android.basic.base.BaseViewModel
import com.starblink.android.basic.config.GuangConfig
import com.starblink.android.basic.ext.toastShowDev
import com.starblink.android.basic.network.base.BaseApiClient
import com.starblink.android.basic.network.base.SkGqlClient
import com.starblink.android.basic.user.UserDataCenter
import com.starblink.android.basic.util.ImageUtils
import com.starblink.basic.apollo.ext.optional
import com.starblink.basic.apollo.ext.optionalOrAbsent
import com.starblink.basic.storage.SkStorage
import com.starblink.basic.util.CommUtils
import com.starblink.home.ui.bean.ApiReqStatusEnum
import com.starblink.home.ui.bean.RvFeedsBrandCollBean
import com.starblink.home.ui.bean.RvFeedsDisCollMultiBrandBean
import com.starblink.home.ui.bean.RvFeedsDisCollSingleBrandBean
import com.starblink.home.ui.bean.RvFeedsDisCollSingleCategoryBean
import com.starblink.home.ui.bean.RvFeedsDisCollSubscribeMerchantBean
import com.starblink.home.ui.bean.RvFeedsOpeSelGifBean
import com.starblink.home.ui.bean.RvFeedsOpeSelVideoBean
import com.starblink.home.ui.bean.RvFeedsOperSelBannerBean
import com.starblink.home.ui.bean.RvFeedsProductBean
import com.starblink.home.ui.bean.RvFeedsWeatherVaneBean
import com.starblink.home.ui.bean.RvNoDataEntity
import com.starblink.home.ui.bean.RvSkeletonEntity
import com.starblink.home.ui.bean.TopBrandOutletsBean
import com.starblink.home.ui.bean.TopSuperStoreBean
import com.starblink.rocketreserver.DiscountMerchantsListV3Query
import com.starblink.rocketreserver.FetchBrandCollectionListV2Query
import com.starblink.rocketreserver.FetchHotAndShadingWordQuery
import com.starblink.rocketreserver.FetchResourceConfigQuery
import com.starblink.rocketreserver.FetchSearchWordConfigQuery
import com.starblink.rocketreserver.HomeFeedsListQuery
import com.starblink.rocketreserver.RecommendVaneQuery
import com.starblink.rocketreserver.fragment.ResourceF
import com.starblink.rocketreserver.fragment.SearchWordVOF
import com.starblink.rocketreserver.type.DirectingVaneProductRecommendQueryParam
import com.starblink.rocketreserver.type.RecommendedForYouFeedQueryReq
import com.starblink.rocketreserver.type.SearchWordConfigRequest
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.launch


class NavHomeVM : BaseViewModel() {

    companion object {

        val KEY_LAST_DISCOUNT_LIST = "last_discount_list_${BaseApiClient.getCurrSvrCfgEnvName()}"

    }

    var pageIndex = 1
    var pageSize = 20
    var autoLoadMore = false

    //默认搜索底纹词
    val emptySearchWord = SearchWordVOF(
        showWord = "Search with just one click",
        actualWord = null,
        linkUrl = null
    )

    //顶部搜索底纹词
    var searchTxtQueue: MutableLiveData<ArrayList<SearchWordVOF>> = MutableLiveData()

    //底纹词对应的热词
    val hotWordsList = arrayListOf<SearchWordVOF>()

    //首页banner
    var bannerObserveData: MutableLiveData<ArrayList<ResourceF>> = MutableLiveData()

    //折扣数据


    var discountStoreNum = 0 //今日折扣数
    var thisMerchantTop3Str: String? = null
    var discountMerchantsData: MutableLiveData<List<DiscountMerchantsListV3Query.MerchantWeb?>?> =
        MutableLiveData()
    var discountAdapterData: ArrayList<TopSuperStoreBean> =
        arrayListOf(
            TopSuperStoreBean(0),
            TopSuperStoreBean(1),
            TopSuperStoreBean(2),
            TopSuperStoreBean(3),
            TopSuperStoreBean(4),
            TopSuperStoreBean(5),
        )


    //品牌数据
    var brandOutletsNum = 0
    var brandLogoList = arrayListOf<String>()
    var brandData: MutableLiveData<List<FetchBrandCollectionListV2Query.BrandList?>?> =
        MutableLiveData()
    var brandIds = arrayListOf<Int>() // 跳转品牌二级页时使用

    //品牌数据骨架填充
    var brandAdapterData: ArrayList<TopBrandOutletsBean> =
        arrayListOf(
            TopBrandOutletsBean(0),
            TopBrandOutletsBean(1),
            TopBrandOutletsBean(2),
        )

    //feeds流  这个破界面各种状态太多 为了减少关联 把骨架图和无数据 当做一个类型处理 RvSkeletonEntity！！！
    var feedsObserveData: MutableLiveData<ArrayList<Any>> = MutableLiveData()

    var lastFeedsSize = 0

    //记录所有接口是否请求成功  这样写稍微灵活一点 随时添加删除
    var allApiCompleted: MutableLiveData<HashMap<ApiReqStatusEnum, Boolean>> = MutableLiveData()

    // 是否显示骨架 初始化第一次只显示一次
    var showSkeleton = true

    var showToastDev2 = false


    val hasInsertVaneOrBrandColl = hashMapOf<Int, Boolean>()


    var fetchingConfig: Boolean = false

    fun initSomeData() {
        allApiCompleted.value = hashMapOf(
            ApiReqStatusEnum.DISCOUNT_MERCHANTS to false,
            ApiReqStatusEnum.BRAND to false,
            ApiReqStatusEnum.BANNER to false,
            ApiReqStatusEnum.FEEDS to false
        )
        searchTxtQueue.value = arrayListOf(emptySearchWord)
        bannerObserveData.value = arrayListOf()
        discountMerchantsData.value = arrayListOf()
        feedsObserveData.value = arrayListOf(RvSkeletonEntity())
    }



//                    bannerObserveData.value?.add(
//                        ResourceF(
//                            id = 1,
//                            name = "",
//                            description = "",
//                            subPic = "",
//                            jumpType = "",
//                            jumpUrl = "",
//                            position = 0,
//                            startTime = "",
//                            endTime = "",
//                            mainPic = "https://img0.baidu.com/it/u=666517787,2620707380&fm=253&fmt=auto&app=120&f=JPEG?w=1140&h=641"
//                        )
//                    )


    private val lastDealIds: MutableList<String> by lazy {
        val tmp = SkStorage.getStringSet(KEY_LAST_DISCOUNT_LIST, emptySet()) ?: emptySet()
        mutableListOf<String>().apply {
            addAll(tmp.mapNotNull { it })
        }
    }

    private var defaultImagesIndex: Int? = null

    fun refreshPageData() {

//        FlowCountDownTimer(time = 3).start(callBack = {
//        }, onFinish = {

        viewModelScope.launch {
            for ((key, _) in allApiCompleted.value!!) {
                allApiCompleted.value!![key] = false
            }

            autoLoadMore = false
            showToastDev2 = SkStorage.getBoolean(GuangConfig.OPEN_HOME_DETAIL_TOAST, false)
            //获取热词
            async {
                val hotWordRsp = SkGqlClient.skQuery(
                    FetchHotAndShadingWordQuery(
                    ),
                )?.data?.fetchHotAndShadingWord
                hotWordRsp.let {
                    searchTxtQueue.value?.clear()
                    if (hotWordRsp != null && !hotWordRsp.shadingWordList.isNullOrEmpty()) {
                        val shadingList = arrayListOf<SearchWordVOF>()
                        hotWordRsp.shadingWordList!!.forEach {
                            if (it?.searchWordVOF != null) {
                                shadingList.add(it.searchWordVOF)
                            }
                        }
                        if (shadingList.isNotEmpty()) {
                            searchTxtQueue.value?.addAll(shadingList)
                        } else {
                            searchTxtQueue.value?.addAll(arrayListOf(emptySearchWord))
                        }
                    } else {
                        searchTxtQueue.value?.addAll(arrayListOf(emptySearchWord))
                    }
                    searchTxtQueue.postValue(searchTxtQueue.value)
                    hotWordsList.clear()
                    hotWordRsp?.hotWordList?.mapNotNull { it?.searchWordVOF }?.let {
                        hotWordsList.addAll(it)
                    }
                }

            }
            //首页banner
            async {
                var banner = SkGqlClient.skQuery(
                    FetchResourceConfigQuery(
                        resourceType = Optional.present(8),
                        operationFeaturedSize = Optional.present(4)
                    ),
                    fetchPolicy = if (!UserDataCenter.isNewDay() && UserDataCenter.queryByCache(
                            UserDataCenter.HOME_CACHE_BANNER_DATA
                        )
                    ) FetchPolicy.CacheFirst else FetchPolicy.NetworkOnly
                )?.data?.fetchResourceConfig
                banner.let {
                    bannerObserveData.value?.clear()
                    if (it.isNullOrEmpty()) {
//                        toastShowDev("没有获取到banner数据", showToastDev2)
                    } else {
                        it.forEach { cfg ->
                            if (cfg?.resourceF != null) {
                                bannerObserveData.value?.add(cfg.resourceF)
                            }
                        }
                        if (it.isNotEmpty()) {
                            UserDataCenter.setQueryByCache(UserDataCenter.HOME_CACHE_BANNER_DATA)
                        }
                    }
                    bannerObserveData.postValue(bannerObserveData.value)
                    refreshApiRspStatus(ApiReqStatusEnum.BANNER)
                }
            }

            //获取折扣
            async {
                //var lastTop3 = getLastTop3()
                val discountMerchants = SkGqlClient.skQuery(
                    DiscountMerchantsListV3Query(
                        pageNo = 1,
                        pageSize = 6,
                        home = true.optional(),
                        countryCode = if (BaseApiClient.getCurrSvrCfgEnvName() == "dev") "SE".optional() else UserDataCenter.getLocalCountryCode()
                            .optional(),
                        lastDealIds = lastDealIds.optionalOrAbsent(),
                        refresh = UserDataCenter.isNewDay(UserDataCenter.NEW_DAY_SCENE_DISCOUNT).optional(),
                        defaultImagesIndex = defaultImagesIndex.optionalOrAbsent(),
                    ),
                    /*fetchPolicy = if (!UserDataCenter.isNewDay() && UserDataCenter.queryByCache(
                            UserDataCenter.HOME_CACHE_DISCOUNT_DATA
                        )
                    ) FetchPolicy.CacheFirst else FetchPolicy.NetworkOnly*/
                )?.data?.discountMerchantsListV3
                discountMerchants.let {
                    thisMerchantTop3Str = null
                    discountStoreNum = 0
                    defaultImagesIndex = it?.defaultImagesIndex
                    if (!it?.url.isNullOrBlank()) {
                        val uri = Uri.parse(it!!.url)
                        val value = uri.getQueryParameter("merchantTop3")
                        if (!value.isNullOrBlank()) {
                            thisMerchantTop3Str = value
                        }
                    }

                    it?.discountStoreNum?.let { num ->
                        discountStoreNum = num
                    }

                    refreshApiRspStatus(ApiReqStatusEnum.DISCOUNT_MERCHANTS)
                    //组合数据
                    it?.merchantWebs.let { list ->
                        list?.map { it.merchantWebVOF.id }?.let {
                            lastDealIds.clear()
                            lastDealIds.addAll(it)
                            async(Dispatchers.IO) {
                                SkStorage.putStringSet(KEY_LAST_DISCOUNT_LIST, lastDealIds.toSet())
                            }
                        }
                        discountMerchantsData.postValue(list)
                        if (!list.isNullOrEmpty()) {
                            UserDataCenter.setQueryByCache(UserDataCenter.HOME_CACHE_DISCOUNT_DATA)
                        }
                    }
                }
            }

            loadBrandData()
            //初始化feeds流 @显乐
            getFeedsData(isRefresh = true) {}
        }

//        })
    }


    /**
     * Brand collection的排序：
     *
     */
    private fun loadBrandData() {
        viewModelScope.async {
            val brandResultData = SkGqlClient.skQuery(
                FetchBrandCollectionListV2Query(
                    pageNo = 1,
                    pageSize = 8,//最少3个显示，最多5个，分别为6,7,8,>8时样式不同
                    isPullDownRefresh = true,
                    scene = 0
                ),
                fetchPolicy = if (!UserDataCenter.isNewDay() && UserDataCenter.queryByCache(
                        UserDataCenter.HOME_CACHE_BRAND_DATA
                    )
                ) FetchPolicy.CacheFirst else FetchPolicy.NetworkOnly
            )?.data?.fetchBrandCollectionListV2
            brandResultData.let { itv2 ->
//                brandDataHasNext = it?.hasNext == true
                brandOutletsNum = 0
                itv2?.brandOutletsNum?.let { num ->
                    brandOutletsNum = num
                }
                brandLogoList.clear()
                val brandLogoIds = mutableListOf<Int>()
                itv2?.brandLogoList?.let { arr ->
                    arr.forEach { str ->
                        str?.let { s ->
                            (s.brandVOF.brandId as? Int)?.let { brandLogoIds.add(it) }
                            brandLogoList.add(s.brandVOF.logo ?: "")
                        }
                    }
                }
                refreshApiRspStatus(ApiReqStatusEnum.BRAND)
                //组合数据
                itv2?.brandList.let { list ->
                    brandData.postValue(list)
                    list?.mapNotNull { it?.brandVOF?.brandId as? Int }?.let {
                        brandIds.addAll(it)
                    }
                    if (!list.isNullOrEmpty()) {
                        UserDataCenter.setQueryByCache(UserDataCenter.HOME_CACHE_BRAND_DATA)
                    }
                }
                brandIds.addAll(brandLogoIds)
            }
        }
    }

    var feedsIndexTag = 0
    inline fun getFeedsData(isRefresh: Boolean, crossinline noData: () -> Unit) {
        viewModelScope.async {
            if (isRefresh) {
                realDataPosition = 0
                pageIndex = 1
                toastShowDev("获取到刷新数据", showToastDev2)
                feedsIndexTag = 0
            } else {
                pageIndex++
                toastShowDev("获取到加载数据", showToastDev2)
            }
            val feeds = SkGqlClient.skQuery(
                HomeFeedsListQuery(
                    params = RecommendedForYouFeedQueryReq(
                        pageNo = pageIndex,
                        pageSize = pageSize
                    )
                ),
                fetchPolicy = if (pageIndex == 1 && !UserDataCenter.isNewDay() && UserDataCenter.queryByCache(
                        UserDataCenter.HOME_CACHE_PRODUCT_DATA
                    )
                ) FetchPolicy.CacheFirst else FetchPolicy.NetworkOnly
            )?.data?.fetchRecommendedForYouFeed
            feeds.let { fd ->
                //添加feeds流
                if (isRefresh) {
                    feedsObserveData.value?.clear()
                }

                if (!fd.isNullOrEmpty()) {
                    val realList = handleFeeds(fd)
//                    val realList = listOf<HomeFeedsListQuery.FetchRecommendedForYouFeed>()
                    if (realList.size == 0) {
//                        toastShowDev("没有获取到feeds流 2", showToastDev2)
                        handleFeedsNoData()
                        noData()
                    } else {
                        autoLoadMore = realList.size > 3
                        feedsObserveData.value?.addAll(realList)
                        feedsObserveData.postValue(feedsObserveData.value)
                        if (realList.isNotEmpty()) {
                            UserDataCenter.setQueryByCache(UserDataCenter.HOME_CACHE_PRODUCT_DATA)
                        }
                    }
                } else {
//                    toastShowDev("没有获取到feeds流 1", showToastDev2)
                    handleFeedsNoData()
                    noData()
                }
                refreshApiRspStatus(ApiReqStatusEnum.FEEDS)
            }
        }
    }

    fun handleFeedsNoData() {
        if (pageIndex == 1) {
            feedsObserveData.value?.addAll(arrayListOf(RvNoDataEntity()))
            feedsObserveData.postValue(feedsObserveData.value)
        } else {
            pageIndex--
        }
    }


    //刷新一下接口是否请求完成的状态
    fun refreshApiRspStatus(enum: ApiReqStatusEnum) {
        if (allApiCompleted.value!![enum] == false) {
            allApiCompleted.value!![enum] = true
            allApiCompleted.postValue(allApiCompleted.value)
        }
    }


    fun vaneOrBrand(
        productId: String?,
        standardSpuIds: String?,
        brandName: String?,
        position: Int,
        hasGetItem: () -> Unit,
    ) {
        viewModelScope.launch {
            val vbResult = SkGqlClient.skQuery(
                RecommendVaneQuery(
                    params = DirectingVaneProductRecommendQueryParam(
                        productId = Optional.present(productId),
                        standardSpuIds = Optional.present(standardSpuIds),
                        index = Optional.present(position),
                        pageNo = Optional.present(pageIndex),
                        queryWay = 1.optional(),
                        pageSize = 7.optional(),
                        countryCode = UserDataCenter.getLocalCountryCode().optional(),
                        brandName = Optional.present(brandName)
                    )
                )
            )?.data?.directingVaneOrBrandCollectionRecommend?.directingVaneOrBrandCollectionVOF
            vbResult?.let {
                //商品集合
                val brandColl = it.brandCollection?.recommendBrandVOF
                //风向标
                val weatherVane = it.directingVane
                if (brandColl?.brand != null) {
                    if (brandColl.productList != null && brandColl.productList!!.size > 6) {
                        feedsObserveData.value?.add(
                            position + 1,
                            RvFeedsBrandCollBean(
                                data = brandColl,
                            )
                        )
                        lastFeedsSize = feedsObserveData.value!!.size
                        hasInsertVaneOrBrandColl[position] = true
//                        toast("获取到一个品牌合集 当前长度 ${brandColl?.productList?.size ?: 0}")
                        hasGetItem()
                    } else {
                    }
                } else if (weatherVane != null) {
                    if (weatherVane.size > 3) {
                        feedsObserveData.value?.add(
                            position + 1,
                            RvFeedsWeatherVaneBean(
                                data = ArrayList(weatherVane),
                            )
                        )
                        hasInsertVaneOrBrandColl[position] = true
                        lastFeedsSize = feedsObserveData.value!!.size
//                        toastShowDev("获取到一个风向标", showToastDev2)
                        hasGetItem()
                    } else {
//                        toastShowDev(
//                            "获取到一个风向标，但返回数据不符合要求 w:${weatherVane?.size ?: 0}",
//                            showToastDev2
//                        )
                    }
                } else {
//                    toastShowDev(
//                        "没有返回风向标.商品集合",
//                        showToastDev2
//                    )
                }
            }
        }
    }

    var realDataPosition = 0

    fun handleFeeds(
        list: List<HomeFeedsListQuery.FetchRecommendedForYouFeed>,
    ): ArrayList<Any> {
        val realList = arrayListOf<Any>()
        list.forEachIndexed { index, it ->
            /// Feed类型（1:素材 2:商品 3:折扣集）
            val feedVOF = it.recommendedForYouFeedVOF
            if (feedVOF.feedType == 1 && feedVOF.material != null) {
                // 素材类型数据
                val typeList = feedVOF.material!!.materialVOF.materialDetailList
                if (!typeList.isNullOrEmpty()) {
                    val vof1 = typeList[0]!!.materialDetailVOF
                    val materialType = vof1.materialType
                    //素材类型（1:图片 2:视频 3:gif）
                    materialType?.let { type ->
                        if (vof1.materialType != null && vof1.jumpUrl != null && vof1.linkUrl != null) {
                            when (type) {
                                1 -> {
                                    realList.add(
                                        RvFeedsOperSelBannerBean(
                                            materialType = 1,
                                            materials = typeList
                                        )
                                    )
                                }

                                2 -> {
                                    realList.add(
                                        RvFeedsOpeSelVideoBean(
                                            materialType = 2,
                                            material = vof1
                                        )
                                    )
                                }

                                3 -> {
                                    realList.add(
                                        RvFeedsOpeSelGifBean(
                                            materialType = 3,
                                            material = vof1
                                        )
                                    )
                                }

                                else -> {}
                            }
                        } else {
                            toastShowDev("接口返回的数据不匹配", showToastDev2)
                        }
                    }
                }
            } else if (feedVOF.feedType == 3 && feedVOF.discountCollection?.discountCollectionVOF != null) {
                // 折扣集类型数据
//                val type = when (feedVOF.discountCollection!!.discountCollectionVOF.type) {
//                    2 -> "多品牌折扣合集"
//                    1, 3 -> "单品牌折扣合集"
//                    4 -> "订阅店铺折扣合集"
//                    5 -> "单类目折扣合集"
//                    0 -> "普通折扣商品卡"
//                    else -> "未知折扣合集"
//                }
//                SKLogger.e(
//                    "dss",
//                    "折扣集类型数据:类型=${type},数据=${feedVOF.discountCollection!!.discountCollectionVOF}"
//                )
                // 折扣集类型 0：非合集；1:偏好单品牌折扣合集,2:偏好品牌折扣合集,3:热门品牌,4:订阅店铺,5-热门类目
                when (feedVOF.discountCollection!!.discountCollectionVOF.type) {
                    2 -> {
                        // 对应多品牌折扣合集
                        realList.add(
                            RvFeedsDisCollMultiBrandBean(feedVOF.discountCollection!!.discountCollectionVOF)
                        )
                    }

                    1, 3 -> {
                        // 对应单品牌折扣合集
                        realList.add(
                            RvFeedsDisCollSingleBrandBean(feedVOF.discountCollection!!.discountCollectionVOF)
                        )
                    }

                    4 -> {
                        // 对应订阅店铺折扣合集
                        realList.add(
                            RvFeedsDisCollSubscribeMerchantBean(feedVOF.discountCollection!!.discountCollectionVOF)
                        )
                    }

                    5 -> {
                        // 对应单类目折扣合集
                        realList.add(
                            RvFeedsDisCollSingleCategoryBean(feedVOF.discountCollection!!.discountCollectionVOF)
                        )
                    }
                }
                // 优化：图片预加载
                feedVOF.discountCollection!!.discountCollectionVOF.imageUrl?.let {
                    ImageUtils.preloadImage(CommUtils.getContext(), it)
                }
            } else if (feedVOF.feedType == 2 && feedVOF.product != null) {
                // 商品类型数据
                realList.add(
                    RvFeedsProductBean(
                        product = feedVOF.product!!,
                        position = index + feedsIndexTag,
                        realDataPosition = realDataPosition
                    )
                )
                realDataPosition++
            }
        }
        feedsIndexTag += realList.size
        return realList
    }


    private fun getLastTop3(): List<String?>? {
        return if (thisMerchantTop3Str == null) {
            null
        } else {
            val top3arr = thisMerchantTop3Str!!.split(",")
            var arr = arrayListOf<String>()
            top3arr.forEach {
                arr.add(it)
            }
            arr
        }
    }

    fun fetchSearchWordConfig(
        word: String,
        wordSearchType: Int = 0,
        call: ((config: FetchSearchWordConfigQuery.FetchSearchWordConfig) -> Unit)? = null,
    ) {
        if (fetchingConfig) return
        viewModelScope.launch {
            fetchingConfig = true
            if (!word.isNullOrEmpty()) {
                val config = SkGqlClient.skQuery(
                    FetchSearchWordConfigQuery(
                        param = SearchWordConfigRequest(
                            type = wordSearchType,
                            searchWord = word,
                        ).optional()
                    ),
                    showDefaultLoading = true,
                )?.data?.fetchSearchWordConfig
                fetchingConfig = false
                if (config != null) {
                    call?.invoke(config)
                } else {
                    call?.invoke(
                        FetchSearchWordConfigQuery.FetchSearchWordConfig(
                            actualWord = word,
                            jumpType = null,
                            jumpUrl = null,
                            goodsRuleId = null,
                        )
                    )
                }
            }
        }
    }
}